package com.karry.yl.web.financial;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.karry.commons.Constants;
import com.karry.commons.base.SuperController;
import com.karry.commons.util.TimeUtil;
import com.karry.commons.vo.JsonResponse;
import com.karry.commons.vo.LayTableResponse;
import com.karry.yl.domain.baseinfo.Organization;
import com.karry.yl.domain.baseinfo.PaymentInfo;
import com.karry.yl.domain.elder.Elderly;
import com.karry.yl.domain.financial.Receipt;
import com.karry.yl.domain.financial.ReceiptItems;
import com.karry.yl.service.baseinfo.OrganizationService;
import com.karry.yl.service.baseinfo.PaymentInfoService;
import com.karry.yl.service.elder.ElderlyService;
import com.karry.yl.service.financial.ReceiptItemsService;
import com.karry.yl.service.financial.ReceiptService;
import com.karry.yl.service.financial.SettlementService;
import org.ponly.payment.util.SignUtils;
import org.ponly.payment.util.XmlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 收款单Controller
 */

@Controller
@RequestMapping("/settlement")
public class SettlementController extends SuperController {
    private static final Logger log = LoggerFactory.getLogger(SettlementController.class);

    @Autowired
    private SettlementService settlementService;
    @Autowired
    private ReceiptItemsService receiptItemsService;
    @Autowired
    private ReceiptService receiptService;
    @Autowired
    private PaymentInfoService paymentInfoService;
    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private ElderlyService elderlyService;

    @RequestMapping
    public String listUI() {
        return "financial/settlement/list";
    }

    @RequestMapping("/list")
    @ResponseBody
    public LayTableResponse list(int page, int limit, String elderlyName, Integer status) {
        elderlyName = StringUtils.isEmpty(elderlyName) ? elderlyName : "%" + elderlyName + "%";
        return settlementService.selectJieSuanPage(page, limit, elderlyName, status, currentUser.getOrgId());
    }

    /**
     * 查询出某个老人的所有未支付的账单
     *
     * @param elderlyId
     * @return
     */
    @RequestMapping("/detail")
    public String detail(Long elderlyId, ModelMap map) {
        //获取该老人的所有的未支付 收费单
        map.put("curr", System.currentTimeMillis());  //结算账单的时间
        List<Receipt> receipts = receiptService.selectList(new EntityWrapper<Receipt>().eq("elderlyId", elderlyId).eq("orgId", currentUser.getOrgId()).eq("deleted", false).eq("status", Receipt.STATUS_ZC));
        map.put("receipts", receipts);
        BigDecimal sum = new BigDecimal(0);
        for (Receipt r : receipts) {
            sum = sum.add(r.getAmount());
            if(r.getType().equals(Receipt.TYPE_QT)){
                List<ReceiptItems> items = receiptItemsService.selectList(new EntityWrapper<ReceiptItems>().eq("receiptId", r.getId()).eq("deleted",false));
                r.setReceiptItemsList(items);
            }
        }
        map.put("sum", sum);
        return "financial/settlement/detail";
    }

    /**
     * 现金收费
     *
     * @param
     * @return
     */
    @RequestMapping("/paycash")
    public String payByCash(Long elderlyId, Long curr,String elderlyIdNo) {
        List<Receipt> receipts = receiptService.selectList(new EntityWrapper<Receipt>().eq("elderlyId", elderlyId).eq("orgId", currentUser.getOrgId()).eq("deleted", false).eq("status", Receipt.STATUS_ZC).le("createdTime", new Date(curr)));
        BigDecimal sum = new BigDecimal(0);
        for (Receipt r : receipts) {
            sum = sum.add(r.getAmount());
        }
        settlementService.payByCash(elderlyId, sum,new Date(curr),currentUser.getOrgId(), new Date(curr),elderlyIdNo,currentUser.getUserName());
        return "redirect:/settlement";
    }

    /**
     * 跳转到支付页面
     *
     * @return
     */
    @RequestMapping("/payment")
    public String paymentUI() {
        return "financial/settlement/online_payment";
    }

    /**
     * 在线支付(微信/支付宝/银联扫码支付)
     *
     * @param elderlyId
     * @param request
     * @return
     * @throws IOException
     */
    @RequestMapping("/payonline")
    public ModelAndView pay(Long elderlyId, String elderlyName,String elderlyIdNo, int channel, Long curr, HttpServletRequest request, HttpSession session) {
        Map<String, String> paramsMap = new HashMap<>();
        String payMethod = null;
        if (channel == 1) {  //微信支付
            paramsMap.put("service", "pay.weixin.native");
            payMethod = "微信";
        } else if (channel == 2) {  //支付宝支付
            paramsMap.put("service", "pay.alipay.native");
            payMethod = "支付宝";
        } else if (channel == 3) {  //银联支付
            paramsMap.put("service", "pay.unionpay.native");
            payMethod = "云闪付";
        }
        paramsMap.put("mch_id", ((PaymentInfo) session.getAttribute(Constants.SK_PAY_INFO)).getMchId());  //商户ID
        String code = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
        paramsMap.put("out_trade_no", code);
        List<Receipt> receipts = receiptService.selectList(new EntityWrapper<Receipt>().eq("elderlyId", elderlyId).eq("orgId", currentUser.getOrgId()).eq("deleted", false).eq("status", Receipt.STATUS_ZC).le("createdTime", new Date(curr)));
        BigDecimal sum = new BigDecimal(0);
        for (Receipt r : receipts) {
            sum = sum.add(r.getAmount());
        }
        paramsMap.put("total_fee", sum.multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP).toString());  //将金额转换为分
        String rname = elderlyName + "结算收费[" + TimeUtil.format(new Date(), "yyyy-MM-dd") + "]";
        paramsMap.put("body", rname);
        paramsMap.put("key", ((PaymentInfo) session.getAttribute(Constants.SK_PAY_INFO)).getKey());  //key
        paramsMap.put("attach", ((PaymentInfo) session.getAttribute(Constants.SK_PAY_INFO)).getId().toString() + "_" + elderlyId + "_" + curr);  //key
        Map<String, String> rs = settlementService.pay(paramsMap);
        if (null != rs && ("0".equals(rs.get("status")) && "0".equals(rs.get("result_code")))) {
            request.setAttribute("receiptName", rname);
            request.setAttribute("elderlyName", elderlyName);
            request.setAttribute("receiptCode", rs.get("out_trade_no"));
            request.setAttribute("payMethod", payMethod);
            return new ModelAndView("financial/settlement/qrcode", "rsMap", rs);  //跳转到二维码支付页面
        } else {
            return new ModelAndView("financial/receipt/fail", "rsMap", rs);
        }
    }


    /**
     * h5在线支付(微信/支付宝/银联扫码支付)
     *
     * @param elderlyId
     * @return
     * @throws IOException
     */
    @RequestMapping("/payonline2")
    public ModelAndView pay2(Long elderlyId, String elderlyName, int channel, Long curr,HttpServletRequest request, Long orgId) {
        Map<String, String> paramsMap = new HashMap<>();
        PaymentInfo paymentInfo = paymentInfoService.selectOne(new EntityWrapper<PaymentInfo>().eq("orgId", orgId));
        String payMethod = null;
        if (channel == 1) {  //微信支付
            paramsMap.put("service", "pay.weixin.native");
            payMethod = "微信";
        } else if (channel == 2) {  //支付宝支付
            paramsMap.put("service", "pay.alipay.native");
            payMethod = "支付宝";
        }
        paramsMap.put("mch_id", paymentInfo.getMchId());  //商户ID
        String code = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
        paramsMap.put("out_trade_no", code);
        List<Receipt> receipts = receiptService.selectList(new EntityWrapper<Receipt>().eq("elderlyId", elderlyId).eq("orgId", orgId).eq("deleted", false).eq("status", Receipt.STATUS_ZC).le("createdTime", new Date(curr)));
        BigDecimal sum = new BigDecimal(0);
        for (Receipt r : receipts) {
            sum = sum.add(r.getAmount());
        }
        paramsMap.put("total_fee", sum.multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP).toString());  //将金额转换为分
        String rname = elderlyName + "结算收费[" + TimeUtil.format(new Date(), "yyyy-MM-dd") + "]";
        paramsMap.put("body", rname);
        paramsMap.put("key",paymentInfo.getKey());  //key
        paramsMap.put("attach", paymentInfo.getId() + "_" + elderlyId + "_" + curr);  //key
        Map<String, String> rs = settlementService.pay(paramsMap);
        if (null != rs && ("0".equals(rs.get("status")) && "0".equals(rs.get("result_code")))) {
            request.setAttribute("receiptName", rname);
            request.setAttribute("elderlyName", elderlyName);
            request.setAttribute("receiptCode", rs.get("out_trade_no"));
            request.setAttribute("payMethod", payMethod);
            return new ModelAndView("financial/settlement/out_pay_qrcode", "rsMap", rs);  //跳转到二维码支付页面
        } else {
            return new ModelAndView("financial/receipt/fail", "rsMap", rs);
        }
    }

    /**
     * 账单支付异步通知
     *
     * @param req
     * @param resp
     */
    @RequestMapping("/pay/notify")
    public void payNotify(HttpServletRequest req, HttpServletResponse resp) {
        try {
            log.debug("收到通知...");
            req.setCharacterEncoding("utf-8");
            resp.setCharacterEncoding("utf-8");
            resp.setHeader("Content-type", "text/html;charset=UTF-8");
            String resString = XmlUtils.parseRequst(req);
            log.debug("请求的内容：" + resString);

            String respString = "error";
            if (resString != null && !"".equals(resString)) {
                Map<String, String> map = XmlUtils.toMap(resString.getBytes(), "utf-8");
                String res = XmlUtils.toXml(map);
                log.debug("请求结果：" + res);
                if (map.containsKey("sign")) {
                    String attach = map.get("attach");
                    String[] attachs = attach.split("_");
                    PaymentInfo paymentInfo = paymentInfoService.selectById(Long.valueOf(attachs[0]));
                    if (!SignUtils.checkParam(map, paymentInfo.getKey())) {
                        respString = "error";
                    } else {
                        String status = map.get("status");
                        if (status != null && "0".equals(status)) {
                            String result_code = map.get("result_code");
                            if (result_code != null && "0".equals(result_code)) {
                                //支付成功，将订单状态修改为 已支付
                                settlementService.updateReceipt(Long.valueOf(attachs[1]), new Date(Long.valueOf(attachs[2])));
                                respString = "success";
                            }
                        }
                    }
                }
            }
            resp.getWriter().write(respString);
        } catch (Exception e) {
            log.error("操作失败，原因：", e);
        }
    }

    /**
     * 客户端轮询,判定是否支付成功
     *
     * @param elderlyId
     * @return
     */
    @RequestMapping("/isPaid")
    @ResponseBody
    public JsonResponse isPaid(Long elderlyId, Long curr) {
        boolean paid = settlementService.isPaid(elderlyId, new Date(curr));
        return JsonResponse.success(paid);
    }


    /**
     * 结算发送后的访问地址
     *
     * @param elderlyId
     * @param map
     * @return
     */
    @RequestMapping("/out_pay")
    public String outPay(Long elderlyId, Long orgId, Long curr, ModelMap map) {
        //获取该老人的所有的未支付 收费单
        map.put("curr", curr);  //结算账单的时间
        Organization org = organizationService.selectById(orgId);
        map.put("org", org);
        Elderly elderly = elderlyService.selectById(elderlyId);
        map.put("elderly", elderly);
        List<Receipt> receipts = receiptService.selectList(new EntityWrapper<Receipt>().eq("elderlyId", elderlyId).eq("orgId", orgId).eq("deleted", false).eq("status", Receipt.STATUS_ZC).le("createdTime", new Date(curr)));
        map.put("receipts", receipts);
        map.put("wzf",receipts.size() > 0);
        BigDecimal sum = new BigDecimal(0);
        for (Receipt r : receipts) {
            sum = sum.add(r.getAmount());
        }
        map.put("sum", sum);
        return "financial/settlement/out_pay";
    }

    /**
     * 在线支付(微信/支付宝/银联扫码支付)
     *
     * @param elderlyId
     * @return
     * @throws IOException
     */
    @RequestMapping("/wappay")
    @ResponseBody
    public JsonResponse wappay(Long elderlyId, String elderlyName, int channel, Long curr,Long orgId) {
        JsonResponse rt;
        Map<String, String> paramsMap = new HashMap<>();
        PaymentInfo paymentInfo = paymentInfoService.selectOne(new EntityWrapper<PaymentInfo>().eq("orgId", orgId));
        String payMethod = null;
        if (channel == 1) {  //微信支付
            paramsMap.put("service", "pay.weixin.wappay");
            payMethod = "微信";
        } /*else if (channel == 2) {  //支付宝支付
            paramsMap.put("service", "pay.alipay.jspay");
            payMethod = "支付宝";
        }*/ else if (channel == 3) {  //银联支付
            paramsMap.put("service", "pay.unionpay.wappay");
            payMethod = "银联";
        }
        paramsMap.put("mch_id", paymentInfo.getMchId());  //商户ID
        String code = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
        paramsMap.put("out_trade_no", code);
        List<Receipt> receipts = receiptService.selectList(new EntityWrapper<Receipt>().eq("elderlyId", elderlyId).eq("orgId", orgId).eq("deleted", false).eq("status", Receipt.STATUS_ZC).le("createdTime", new Date(curr)));
        BigDecimal sum = new BigDecimal(0);
        for (Receipt r : receipts) {
            sum = sum.add(r.getAmount());
        }
        paramsMap.put("total_fee", sum.multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP).toString());  //将金额转换为分
        String rname = elderlyName + "结算收费[" + TimeUtil.format(new Date(), "yyyy-MM-dd") + "]";
        paramsMap.put("body", rname);
        paramsMap.put("key",paymentInfo.getKey());  //key
        paramsMap.put("attach", paymentInfo.getId() + "_" + elderlyId + "_" + curr);  //key
        paramsMap.put("callback_url","https://www.kerry365.com/settlement/pay/callback");
        paramsMap.put("device_info","AND_WAP");
        paramsMap.put("mch_app_name","陕西养老服务信息平台");
        paramsMap.put("mch_app_id","https://www.kerry365.com");
        Map<String, String> rs = settlementService.pay(paramsMap);
        if (null != rs && ("0".equals(rs.get("status")) && "0".equals(rs.get("result_code")))) {
            rs.put("receiptName", rname);
            rs.put("elderlyName", elderlyName);
            rs.put("receiptCode", rs.get("out_trade_no"));
            rs.put("payMethod", payMethod);
            rt = JsonResponse.success(rs);
        } else {
            rt = JsonResponse.fail("操作失败",rs);
        }
        return rt;
    }

    @RequestMapping("/pay/callback")
    public String callbackUrl(){
        return "financial/settlement/pay_success";
    }
}
